import { useEffect,useState } from 'react';
import axios, { AxiosRequestConfig } from 'axios';

//重新获取token
async function refreshToken() {
  const res = await axios.get('http://localhost:3000/user/refresh', {
      params: {
        refresh_token: localStorage.getItem('refresh_token')
      }
  });
  localStorage.setItem('access_token', res.data.access_token || '');
  localStorage.setItem('refresh_token', res.data.refresh_token || '');
  return res;
}

//请求拦截器(将local的token添加到authorization请求头)
axios.interceptors.request.use(function (config) {
  const accessToken = localStorage.getItem('access_token');
  if(accessToken) {
    config.headers.authorization = 'Bearer ' + accessToken;
  }
  return config;
})


interface PendingTask {
  config: AxiosRequestConfig
  resolve: Function
}
let refreshing = false;
const queue: PendingTask[] = [];


//响应拦截器
axios.interceptors.response.use(
  (response) => { return response; },

  //如果响应失败 -> token过期
  async (error) => {
    let { data, config } = error.response;


    //解决重复刷新的问题
    //加一个 refreshing 的标记，如果在刷新，那就返回一个 promise，并且把它的 resolve 方法还有 config 加到队列里。
    if(refreshing) {
      return new Promise((resolve) => {
          queue.push({
              config,
              resolve
          });
      });
    }

    //如果响应失败，且不是直接访问/user/refresh
    if (data.statusCode === 401 && !config.url.includes('/user/refresh')) {
      refreshing = true;
      const res = await refreshToken(); //重新获取token
      refreshing = false;

      if(res.status === 200) {
        queue.forEach(({config, resolve}) => {
          resolve(axios(config))
        })
        return axios(config);
      } else {
        alert('登录过期，请重新登录');
        return Promise.reject(res.data)
      }
        
    } else {
      return error.response;
    }
  }
)

function App() {
  const [aaa,setAaa] = useState();
  const [bbb,setBbb] = useState();
  
  async function login(){
    const res = await axios.post('http://127.0.0.1:3000/user/login',{
      username: 'newking',
      password: '111111'
    })
    localStorage.setItem('access_token',res.data.access_token);
    localStorage.setItem('refresh_token',res.data.refresh_token);
  }
  async function query(){
    //没有token的时候登录,并将token保存进localstorage
    if(!localStorage.getItem('access_token')){
      await login();
    }

    await [
      axios.get('http://localhost:3000/bbb'),
      axios.get('http://localhost:3000/bbb'),
      axios.get('http://localhost:3000/bbb')
    ];

    const { data: aaaData } = await axios.get('http://127.0.0.1:3000/aaa');
    const { data: bbbData } = await axios.get('http://127.0.0.1:3000/bbb');

    setAaa(aaaData);
    setAaa(bbbData);
  }

  useEffect(()=>{
    query();
  },[])


  return (
   <div>
     <p>{aaa}</p>
     <p>{bbb}</p>
   </div>
  );
}

export default App;
